package com.youpai.platform.order.service.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.youpai.platform.biggod.service.entity.po.BigGodPO;
import com.youpai.platform.biggod.service.entity.po.SkillPO;
import com.youpai.platform.biggod.service.mapper.BigGodMapper;
import com.youpai.platform.biggod.service.mapper.SkillMapper;
import com.youpai.platform.chat.service.constant.ChatConstants;
import com.youpai.platform.chat.service.entity.dto.CreateOrderSystemMsgDTO;
import com.youpai.platform.chat.service.entity.dto.SendSystemMessageDTO;
import com.youpai.platform.chat.service.entity.dto.SystemMessageDTO;
import com.youpai.platform.chat.service.entity.po.ChatAccountPO;
import com.youpai.platform.chat.service.mapper.ChatAccountMapper;
import com.youpai.platform.chat.service.service.SystemMessageService;
import com.youpai.platform.chat.service.util.ChatUtils;
import com.youpai.platform.common.enums.ProcessCodeEnum;
import com.youpai.platform.common.exceptions.BaseBizException;
import com.youpai.platform.common.util.CommonCons;
import com.youpai.platform.common.util.StringUtils;
import com.youpai.platform.common.util.UserContext;
import com.youpai.platform.common.util.id.IdGenerator;
import com.youpai.platform.order.service.convert.OrderConverter;
import com.youpai.platform.order.service.entity.po.OrderEvaluatePO;
import com.youpai.platform.order.service.entity.po.OrderPO;
import com.youpai.platform.order.service.enums.OrderStatusEnum;
import com.youpai.platform.order.service.mapper.OrderEvaluateMapper;
import com.youpai.platform.order.service.mapper.OrderMapper;
import com.youpai.platform.order.service.service.OrderService;
import com.youpai.platform.order.web.entity.dto.OrderDto;
import com.youpai.platform.order.web.entity.dto.OrderListDto;
import com.youpai.platform.order.web.entity.req.*;
import com.youpai.platform.order.web.entity.resp.OrderResp;
import com.youpai.platform.user.service.entity.po.UserPO;
import com.youpai.platform.user.service.mapper.UserMapper;
import com.youpai.platform.user.web.entity.dto.UserDTO;
import com.youpai.platform.vulture.common.enums.AppIdEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @time: 2022/8/4 1:32 下午
 * @author: welles
 * @description: 订单service实现类
 */
@Slf4j
@Component
public class OrderServiceImpl implements OrderService {

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private OrderEvaluateMapper orderEvaluateMapper;

    @Resource
    private SkillMapper skillMapper;

    @Resource
    private UserMapper userMapper;

    @Resource
    private ChatAccountMapper chatAccountMapper;

    @Resource
    private BigGodMapper bigGodMapper;

    @Resource
    private SystemMessageService systemMessageService;

    @Override
    public OrderResp createOrder(CreateOrderReq req) {
        //通过登录态 获取用户UID
        UserDTO userDTO = UserContext.getUserContext();
        //做判断，抛用户登录异常
        if (userDTO == null) {
            log.error("用户登录异常!");
            throw new BaseBizException(ProcessCodeEnum.USER_LOGIN_ERROR);
        }
        String uid = userDTO.getUid();
        SkillPO skillPO = skillMapper.get(Long.valueOf(req.getSkillId()));
        //判断技能是否存在
        if (skillPO == null) {
            log.error("当前选择技能不存在!");
            throw new BaseBizException(ProcessCodeEnum.SKILL_NOT_EXIST);
        }
        Double price = skillPO.getUnitPrice();
        Double sumPrice = req.getCount() * price;
        Long defaultOrderId = CommonCons.DEFAULT_ID.ORDER_ID;
        Long generateOrderId = IdGenerator.generateId();
        Long orderId = StringUtils.getId(defaultOrderId, generateOrderId);
        OrderPO orderPO = new OrderPO(orderId, Long.valueOf(uid), skillPO.getGodUid(),
                skillPO.getSkillId(), req.getCount(), price, sumPrice, OrderStatusEnum.PLACE_ORDER.status);
        boolean flag = orderMapper.add(orderPO) > 0;
        SendSystemMessageDTO systemMessageDTO = buildSystemMessageDTO(orderPO);
        systemMessageService.sendSystemMessage(systemMessageDTO);
        if (flag) {
            return new OrderResp().setHintText("新增订单成功!");
        } else {
            log.error("新增订单失败!");
            throw new BaseBizException(ProcessCodeEnum.ORDER_ADD_EXCEPTION);
        }
    }

    private SendSystemMessageDTO buildSystemMessageDTO(OrderPO orderPO) {
        CreateOrderSystemMsgDTO createOrderSystemMsgDTO = buildCreateOrderSystemMsgDTO(orderPO);
        SystemMessageDTO systemMessageDTO = new SystemMessageDTO();
        systemMessageDTO.setMsg(JSONObject.toJSONString(createOrderSystemMsgDTO))
                .setScheme("kila://");
        SendSystemMessageDTO sendSystemMessageDTO = new SendSystemMessageDTO();
        sendSystemMessageDTO.setSystemUid(ChatConstants.SYSTEM_COUNT_ACC_ID)
                .setSystemAccId(ChatUtils.buildAccId(AppIdEnum.KILA.appId, String.valueOf(ChatConstants.SYSTEM_COUNT_ACC_ID)))
                .setAppId(AppIdEnum.KILA.appId)
                .setUid(String.valueOf(orderPO.getBigGodUid()))
                .setContent(JSONObject.toJSONString(systemMessageDTO));
        return sendSystemMessageDTO;
    }

    private CreateOrderSystemMsgDTO buildCreateOrderSystemMsgDTO(OrderPO orderPO) {
        UserDTO userDTO = UserContext.getUserContext();
        CreateOrderSystemMsgDTO createOrderSystemMsgDTO = new CreateOrderSystemMsgDTO();
        createOrderSystemMsgDTO.setBossGender(userDTO.getGender())
                .setOrderId(String.valueOf(orderPO.getOrderId()))
                .setCreateTime(new Date())
                .setOrderStatus(orderPO.getOrderStatus())
                .setBossNickName(userDTO.getNickName())
                .setBossAvatar(userDTO.getAvatar())
                .setBossUid(userDTO.getUid())
                .setNumber(orderPO.getCount());
        return createOrderSystemMsgDTO;
    }

    @Override
    public OrderResp updateOrderStatus(UpdateOrderReq req) {
        //通过登录态获取用户
        UserDTO userDTO = UserContext.getUserContext();
        if (userDTO == null) {
            log.error("用户登录异常!");
            throw new BaseBizException(ProcessCodeEnum.USER_LOGIN_ERROR);
        }
        //通过orderId判断当前订单是否存在，如果不存在抛当前订单不存在
        OrderPO orderPO = orderMapper.get(Long.valueOf(req.getOrderId()));
        if (orderPO == null) {
            log.error("当前订单不存在!");
            throw new BaseBizException(ProcessCodeEnum.ORDER_NOT_EXIST);
        }
        //判断登录的用户uid和订单的bossUid是否相同
//        if (!userDTO.getUid().equals(String.valueOf(orderPO.getBossUid()))) {
//            log.error("当前登录用户和当前订单用户不一致!");
//            throw new BaseBizException(ProcessCodeEnum.LOGIN_USER_ORDER_USER_NOT_AGREEMENT);
//        }
        boolean flag = orderMapper.updateStatus(Long.valueOf(req.getOrderId()), req.getStatus()) > 0;
        if (flag) {
            return new OrderResp().setHintText("修改订单状态成功!");
        } else {
            log.error("修改订单状态失败!");
            throw new BaseBizException(ProcessCodeEnum.ORDER_STATUS_UPDATE_EXCEPTION);
        }
    }

    @Override
    public OrderDto getOrder(GetOrderReq req) {
        OrderPO orderPO = orderMapper.get(Long.valueOf(req.getOrderId()));
        if (orderPO == null) {
            log.error("当前订单不存在!");
            throw new BaseBizException(ProcessCodeEnum.ORDER_NOT_EXIST);
        }
        Long uid = null;
        if (req.getUid().equals(String.valueOf(orderPO.getBossUid()))) {
            uid = orderPO.getBossUid();
        } else {
            uid = orderPO.getBigGodUid();
        }
        UserPO userPO = userMapper.getUsersByUid(uid);
        ChatAccountPO chatAccountPO = chatAccountMapper.getChatAccountPOsByUid(uid);
        SkillPO skillPO = skillMapper.get(orderPO.getSkillId());
        return OrderConverter.convertOrderPOToOrderDto(orderPO, chatAccountPO, userPO, skillPO);
    }

    @Override
    public OrderPO getOrder(String uid) {
        if(org.springframework.util.StringUtils.isEmpty(uid)){
            log.error("订单UID不能为空!");
            throw new BaseBizException(ProcessCodeEnum.ORDER_ID_ISNULL);
        }
        return orderMapper.get(Long.valueOf(uid));
    }

    @Override
    public List<OrderListDto> listOrder(ListOrderReq req) {
        BigGodPO bigGodPO = bigGodMapper.get(Long.valueOf(req.getUid()));
        List<OrderPO> orderPOS = new ArrayList<>();
        if (bigGodPO == null) {
            System.out.println(Long.valueOf(req.getUid()));
            orderPOS = orderMapper.getByUid(Long.valueOf(req.getUid()), null, req.getOrderStatus(), 0, 100);
        } else {
            orderPOS = orderMapper.getByUid(null, Long.valueOf(req.getUid()), req.getOrderStatus(), 0, 100);
        }
        if (CollectionUtils.isEmpty(orderPOS)) {
            return new ArrayList<>();
        }
        List<Long> orderIds = orderPOS.stream().map(OrderPO::getOrderId).collect(Collectors.toList());
        //根据orderIds获取评价列表
        List<OrderEvaluatePO> orderEvaluatePOS = orderEvaluateMapper.getEvaluateList(orderIds);
        //评价转为map
        Map<Long, OrderEvaluatePO> orderEvaluatePOMap = null;
        if (CollectionUtils.isEmpty(orderEvaluatePOS)) {
            orderEvaluatePOMap = new HashMap<>();
        } else {
            orderEvaluatePOMap = orderEvaluatePOS.stream().collect(
                    Collectors.toMap(OrderEvaluatePO::getOrderId, orderEvaluatePO -> orderEvaluatePO));
        }
        List<Long> skillIds = orderPOS.stream().map(OrderPO::getSkillId).collect(Collectors.toList());
        List<SkillPO> skillPOS = skillMapper.list(skillIds);
        Map<Long, String> skillNameMap = skillPOS.stream().collect(
                Collectors.toMap(SkillPO::getSkillId, SkillPO::getSkill));
        List<Long> godUids = skillPOS.stream().map(SkillPO::getGodUid).collect(Collectors.toList());
        List<UserPO> godUsers = userMapper.getUsersByUids(godUids);
        Map<Long, String> godNameMap = godUsers.stream().collect(
                Collectors.toMap(UserPO::getUid, UserPO::getNickName));
        return OrderConverter.convertOrderPOsToOrderDtos(orderPOS, skillNameMap, godNameMap, orderEvaluatePOMap);
    }

    @Override
    public OrderResp payOrder(PayOrderReq req) {
        boolean flag = orderMapper.updateStatus(Long.valueOf(req.getOrderId()), OrderStatusEnum.PLACE_ORDER.status) > 0;
        if (flag) {
            return new OrderResp().setHintText("支付成功!");
        } else {
            log.error("支付失败!");
            throw new BaseBizException(ProcessCodeEnum.PAY_EXCEPTION);
        }
    }
}
